/*
 * File FileSender.java 
 */
package cs.ni;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Observable;
import cs.entity.UserFile;

/**
 * Thread created to sending a file via TCP
 * to a remote user <p>
 * Package  cs.ni
 * Project ChatSystemG1 - INSA 4INFOA1 - 2013/2014
 * @author Julie DUMONS & Juste OUEDRAOGO
 */
public class FileSender extends Observable implements Runnable {
	/**
	 * Socket used to send the file
	 */
	private Socket socket;
	
	/**
	 * UserFile needs to be sent
	 */
	private UserFile file;
	
	/**
	 * Ip address of destination
	 */
	private InetAddress remoteaddr;
	
	/**
	 * Constructor of FileSender
	 * @param file needs to be sent
	 * @param servAddr 
	 * @param port
	 */
	public FileSender(UserFile file, InetAddress servAddr, int port){
		try {
			this.file = file;
			this.socket = new Socket(servAddr, port);
			this.remoteaddr = servAddr;
		} catch (IOException e) {
			setChanged();
			file.setState(UserFile.State.FAILED);
			notifyObservers(file);
		}
	}
	@Override
	public void run() {
	
		try {
			
		    // Get the size of the file
		    long length = file.getFile().length();
		    if (length > Integer.MAX_VALUE) {
		        System.out.println("File is too large.");
		    }
		    byte[] bytes = new byte[(int) length];
		    FileInputStream fis = new FileInputStream(file.getFile());
		    BufferedInputStream bis = new BufferedInputStream(fis);
		    BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

		    int count;

		    while ((count = bis.read(bytes)) > 0) {
		        out.write(bytes, 0, count);
		    }

		    out.flush();
		    out.close();
		    fis.close();
		    bis.close();
		    socket.close();
			//notify the observers (chat ni) that the upload have completed
			setChanged();
			file.setState(UserFile.State.COMPLETED);
			notifyObservers(file);
			System.out.println("file sent "+file.getFile().getName()+" size: "+file.getFile().length());
			
		} catch (IOException e) {
			setChanged();
			file.setState(UserFile.State.FAILED);
			notifyObservers(file);
		}
		
	}

}
